/*global pi, document, self */
// 连接模块，负责管理连接，提供统一入口，根据模块的配置参数，连接实际由具体的连接工厂创建。
// 所有的连接都应该实现request, send, isActive, getUrl, getActiveTime, close
// 上下行的消息都是{cmd, ktvlist}的结构，cmd和kv中k都是字符串，t为类型，v为整数、浮点、字符串和二进制数据。

pi.mod.define('pi.connect', function(factoryTable) {
	"use strict";
	// 定义模块
	var module = {},
	table = {},
	factory = {},
	listener = [],
	broadcast = function(e) {
		var i;
		for (i = listener.length - 1; i >= 0; i--) {
			try {
				listener[i](e);
			} catch(ex) {
				if (pi.log) {
					pi.log("pi.connect, ex: " + ex);
				}
			}
		}
	};

	// 获得指定url连接
	module.get = function(url) {
		return table[url];
	};
	// 打开连接
	module.open = function(url, cfg, callback, timeout) {
		var i, protocol, con = table[url];
		if (con) {
			return callback(con);
		}
		i = url.indexOf("://");
		if (i < 1) {
			return callback({
				error: -13,
				reason: "invalid url:" + url
			});
		}
		protocol = url.slice(0, i);
		con = factory[protocol];
		if (!con) {
			con = factoryTable[protocol];
			if (!con) {
				return callback({
					error: -13,
					reason: "undefined protocol:" + protocol
				});
			}
			con = pi.mod.get(con);
			if (!con) {
				return callback({
					error: -13,
					reason: "unload factory:" + protocol
				});
			}
			factory[protocol] = con;
			con.receive = function(e) {
				broadcast(e);
			};
		}
		return con.open(url, cfg, callback, timeout);
	};
	// 用指定url连接发送请求
	module.request = function(url, msg, callback, timeout) {
		var con = table[url];
		if (con) {
			con.request(msg, callback, timeout);
			return true;
		}
		return false;
	};
	// 用指定url连接发送消息
	module.send = function(url, msg) {
		var con = table[url];
		if (con) {
			con.send(msg);
			return true;
		}
		return false;
	};
	// 关闭指定url连接
	module.close = function(url) {
		var con = table[url];
		if (con) {
			con.close();
			delete table[url];
			broadcast({
				type: "close",
				con: con
			});
			return true;
		}
		return false;
	};
	// 添加连接事件监听器
	module.addListener = function(handler) {
		listener.push(handler);
	};
	// 移除连接事件监听器
	module.removeListener = function(handler) {
		var i;
		for (i = listener.length - 1; i >= 0; i--) {
			if (listener[i] === handler) {
				listener.splice(i, 1);
				return true;
			}
		}
		return false;
	};

	return module;
});